﻿namespace KeRui.Upload
{
    using System;

    internal class StateInfo
    {
        private int mBytesDone;
        private int mBytesTotal;
        private int mDataIndex;
        private int[] mDataSize;
        private DateTime[] mDataTime;
        private byte[] mFileName;
        private bool mFinished;
        private int mID;
        private string mNote;
        private bool mStarted;
        private DateTime mStartTime;
        private DateTime mTouchTime;

        public StateInfo(int inID, string inNote, int inChunkSize)
        {
            int num;
            this.mID = inID;
            this.mBytesTotal = 0;
            this.mBytesDone = 0;
            this.mStarted = false;
            this.mFinished = false;
            this.mStartTime = DateTime.Now;
            this.mTouchTime = DateTime.Now;
            this.mNote = inNote;
            this.mFileName = new byte[0];
            int num2 = 1;
            if ((inChunkSize > 0) && (inChunkSize < 0x10000))
            {
                num2 = 0x10000 / inChunkSize;
            }
            this.mDataIndex = 0;
            this.mDataTime = new DateTime[num2];
            for (num = 0; num < num2; num++)
            {
                this.mDataTime[num] = this.mTouchTime;
            }
            this.mDataSize = new int[num2];
            for (num = 0; num < num2; num++)
            {
                this.mDataSize[num] = 0;
            }
        }

        public double BytesPerSecondAverage()
        {
            double num = 0.0;
            double num2 = this.ElapsedMS / 1000.0;
            if (num2 > 0.0)
            {
                num = ((double) this.mBytesDone) / num2;
            }
            return num;
        }

        public double BytesPerSecondCurrent()
        {
            double num = 0.0;
            int index = this.mDataIndex - 1;
            if (index < 0)
            {
                index = this.mDataTime.Length - 1;
            }
            int num3 = index + 1;
            if (num3 >= this.mDataTime.Length)
            {
                num3 = 0;
            }
            double totalSeconds = this.mDataTime[index].Subtract(this.mDataTime[num3]).TotalSeconds;
            if (totalSeconds <= 0.0)
            {
                return num;
            }
            int num5 = 0;
            int length = this.mDataSize.Length;
            for (int i = 0; i < length; i++)
            {
                num5 += this.mDataSize[i];
            }
            return (((double) num5) / totalSeconds);
        }

        public bool Expired()
        {
            return (DateTime.Compare(this.mTouchTime.AddSeconds(60.0), DateTime.Now) < 0);
        }

        public double PercentDone()
        {
            double num = 0.0;
            if ((this.mBytesDone == this.mBytesTotal) && this.mFinished)
            {
                num = 100.0;
            }
            else if (this.mBytesTotal > 0)
            {
                num = (((double) this.mBytesDone) / ((double) this.mBytesTotal)) * 95.0;
            }
            return (double) ((int) num);
        }

        public double SecondsLeft()
        {
            double num = 0.0;
            double elapsedMS = this.ElapsedMS;
            if (this.mBytesDone > 0)
            {
                num = ((((double) this.mBytesTotal) / ((double) this.mBytesDone)) * elapsedMS) - elapsedMS;
            }
            return (num / 1000.0);
        }

        public void SetState(int inDone, int inTotal)
        {
            int num = inDone - this.mBytesDone;
            this.mBytesDone = inDone;
            this.mBytesTotal = inTotal;
            this.mStarted = true;
            this.mTouchTime = DateTime.Now;
            this.mDataTime[this.mDataIndex] = this.mTouchTime;
            this.mDataSize[this.mDataIndex] = num;
            if (++this.mDataIndex >= this.mDataTime.Length)
            {
                this.mDataIndex = 0;
            }
        }

        public void Touch()
        {
            this.mTouchTime = DateTime.Now;
        }

        public int BytesDone
        {
            get
            {
                this.Touch();
                return this.mBytesDone;
            }
        }

        public int BytesTotal
        {
            get
            {
                this.Touch();
                return this.mBytesTotal;
            }
        }

        public double ElapsedMS
        {
            get
            {
                this.Touch();
                return DateTime.Now.Subtract(this.mStartTime).TotalMilliseconds;
            }
        }

        public byte[] FileName
        {
            get
            {
                this.Touch();
                return this.mFileName;
            }
            set
            {
                this.mFileName = value;
            }
        }

        public bool Finished
        {
            get
            {
                this.Touch();
                return this.mFinished;
            }
            set
            {
                this.mFinished = value;
            }
        }

        public int ID
        {
            get
            {
                return this.mID;
            }
        }

        public string Note
        {
            get
            {
                this.Touch();
                return this.mNote;
            }
            set
            {
                this.mNote = value;
            }
        }

        public bool Started
        {
            get
            {
                this.Touch();
                return this.mStarted;
            }
        }
    }
}

